package com.freecloud.javabasics.jvm;

import com.freecloud.common.LoggerUtil;

/**
 * 测试GC时，调用finalize()方法，可使对象拯救自己一次
 * -Xms20M -Xmx20M -Xmn10M -Xss2m -XX: +UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:PretenureSizeThreshold=6M -XX:-HeapDumpOnOutOfMemoryError
 * @Author: maomao
 * @Date: 2021-03-23 15:54
 */
public class FinalizeEscapeGC {

    public static FinalizeEscapeGC SAVE_HOOK = null;

    public void isAlive() {
        LoggerUtil.printThread("对象还活着");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        LoggerUtil.printThread("执行finalize方法!将对象救活一次！");
        FinalizeEscapeGC.SAVE_HOOK = this;
    }


    public static void main(String[] args) throws Throwable {
        SAVE_HOOK = new FinalizeEscapeGC();
        LoggerUtil.printThread("测试对象GC后，是否还可激活！");
        for (int i = 0; i < 5; i++) {
            rescueTest(i);
        }
    }

    private static void rescueTest(int index) throws Throwable{
        //第二次拯救失败
        SAVE_HOOK = null;
        LoggerUtil.printThread(index + " 调用GC！");
        System.gc();
        //因为finalize方法优先级很低，所以暂停0.5s等待
        Thread.sleep(500);
        if (SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            LoggerUtil.printThread(index + " 对象已销毁，只有执行一次，之后无效！");
        }
    }
}
